package com.weng.cloud.service8881.ribbon;

import com.netflix.loadbalancer.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @Author: weng
 * @Date: 2022/3/2
 * @Description: com.weng.cloud.service8881.ribbon
 *
 * 配置类不能被启动类扫描到（即不能放在启动类的包或者子包下），否则会成为全局配置：
 * 我们的做法：
 *  方式一：放在不同的包下。
 *  方式二：启动类排除该配置类
 *      https://www.cnblogs.com/dbaxyx/p/8808940.html
 */
//@Configuration
public class RibbonCfg {

    /**
     * <br/>function: 默认就是轮询
     * <br/>tip:
     *
     * @param: []
     * @return: com.netflix.loadbalancer.IRule
     * @author: weng
     * @date: 2022/3/2 22:15
     */
    //@Bean
    public IRule roundRobinRule(){
        return new RoundRobinRule();
    }

    //@Bean
    public IRule randomRule(){
        return new RandomRule();
    }

    /**
     * 轮询失败重试策略
     * 轮询失败重试策略（RetryRule）是这样工作的，首先使用轮询策略进行负载均衡，
     * 如果轮询失败，则再使用轮询策略进行一次重试，相当于重试下一个节点，看下一个节点是否可用，如果再失败，则直接返回失败。
     * @return
     */
    //@Bean
    public IRule retryRule() {
        //这里可以同配置文件一样配置重试参数
        return new RetryRule();
    }


    /**
     *  响应时间权重策略
     *  策略描述：根据响应时间，分配一个权重weight，响应时间越长，weight越小，被选中的可能性越低。
     * @return
     */
    public IRule weightedResponseTimeRule() {
        return new WeightedResponseTimeRule();
    }


    /**
     *  并发量最小可用策略
     *  策略描述：选择一个并发量最小的server返回。如何判断并发量最小呢？ServerStats有个属性activeRequestCount，
     *  这个属性记录的就是server的并发量。轮询所有的server，选择其中activeRequestCount最小的那个server，就是并发量最小的服务节点。
     * @return
     */
    public IRule bestAvailableRule() {
        return new BestAvailableRule();
    }


    /**
     *  可用过滤策略
     *  策略描述：过滤掉连接失败的服务节点，并且过滤掉高并发的服务节点，然后从健康的服务节点中，使用轮询策略选出一个节点返回。
     * @return
     */
    public IRule availabilityFilteringRule() {
        return new AvailabilityFilteringRule();
    }


    /**
     *
     *  策略描述：复合判断server所在区域的性能和server的可用性，来选择server返回。
     * @return
     */
    public IRule zoneAvoidanceRule() {
        return new ZoneAvoidanceRule();
    }

    /**
     * 读取自定义配置
     * @return HttpComponentsClientHttpRequestFactory
     */
/*    @Bean
    @ConfigurationProperties(prefix = "custom.request-factory")
    public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){
        return new HttpComponentsClientHttpRequestFactory();
    }

    @Bean // 交给spring管理
    @LoadBalanced // 开启负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate(httpComponentsClientHttpRequestFactory());
    }*/
}
